package com.saasovation.collaboration.port.adapter.spring;

import com.saasovation.collaboration.domain.model.calendar.CalendarEntryRepository;
import com.saasovation.collaboration.domain.model.calendar.CalendarIdentityService;
import com.saasovation.collaboration.domain.model.calendar.CalendarRepository;
import com.saasovation.collaboration.domain.model.collaborator.CollaboratorService;
import com.saasovation.collaboration.domain.model.forum.DiscussionRepository;
import com.saasovation.collaboration.domain.model.forum.ForumIdentityService;
import com.saasovation.collaboration.domain.model.forum.ForumRepository;
import com.saasovation.collaboration.domain.model.forum.PostRepository;
import com.saasovation.collaboration.port.adapter.persistence.repository.*;
import com.saasovation.collaboration.port.adapter.service.HttpUserInRoleAdapter;
import com.saasovation.collaboration.port.adapter.service.TranslatingCollaboratorService;
import com.saasovation.collaboration.port.adapter.service.UserInRoleAdapter;
import com.saasovation.common.event.sourcing.EventStore;
import com.saasovation.common.port.adapter.persistence.eventsourcing.leveldb.LevelDBEventStore;
import com.saasovation.common.port.adapter.persistence.eventsourcing.mysql.MySQLEventStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

@Configuration
public class DomainConfiguration {

    @Bean
    public CalendarEntryRepository calendarEntryRepository(EventStore eventStore) {
        return new EventStoreCalendarEntryRepository(eventStore);
    }

    @Bean
    public CalendarRepository calendarRepository(EventStore eventStore) {
        return new EventStoreCalendarRepository(eventStore);
    }

    @Bean
    public CalendarIdentityService calendarIdentityService(CalendarRepository aCalendarRepository,
                                                           CalendarEntryRepository aCalendarEntryRepository) {
        return new CalendarIdentityService(aCalendarRepository,
                aCalendarEntryRepository);
    }

    @Bean
    public DiscussionRepository discussionRepository(EventStore eventStore) {
        return new EventStoreDiscussionRepository(eventStore);
    }

    @Bean
    public ForumRepository forumRepository(EventStore eventStore) {
        return new EventStoreForumRepository(eventStore);
    }

    @Bean
    public PostRepository postRepository(EventStore eventStore) {
        return new EventStorePostRepository(eventStore);
    }

    @Bean
    public ForumIdentityService forumIdentityService(ForumRepository aForumRepository,
                                                     DiscussionRepository aDiscussionRepository,
                                                     PostRepository aPostRepository) {
        return new ForumIdentityService(aForumRepository,
                aDiscussionRepository,
                aPostRepository);
    }

    @Bean
    public CollaboratorService collaboratorService(UserInRoleAdapter aUserInRoleAdapter) {
        return new TranslatingCollaboratorService(aUserInRoleAdapter);
    }

    @Bean
    @Profile("!test")
    public UserInRoleAdapter userInRoleAdapter() {
        return new HttpUserInRoleAdapter();
    }

    @Bean
    public EventStore eventStore(NamedParameterJdbcTemplate jdbcTemplate) {
        return new MySQLEventStore(jdbcTemplate);
    }

    //@Bean
    public EventStore eventStore(@Value("leveldb.event-store.path")
                                 String levelDBEventStorePath) {
        if (levelDBEventStorePath == null || levelDBEventStorePath.isEmpty()) {
            throw new IllegalArgumentException("levelDB eventStore path is null or empty");
        }
        return new LevelDBEventStore(levelDBEventStorePath);
    }
}
